package SpLib.Net
{
	import SpLib.Com.SingletonFactory;
	import SpLib.Tools.TDF;
	import SpLib.Com.SpLibEvent;
	
	import flash.events.*;
	import flash.net.URLLoader;
	import flash.net.URLRequest;

	public class URLResMgr extends EventDispatcher
	{
		public static const FILEINFO_DOWNING:String = "SpLibDonwFileInfoWorking";
		public static const FILEINFO_COMPLETE:String = "SpLibDonwFileInfoComplete";
		public static const FILEINFO_FAIL:String = "SpLibDonwFileInfoFail";
		
		public static var s_sUrlPath:String = "";
	
		private static var s_Instance:URLResMgr = null;
		public static const s_MaxRegetTimes:int = 3;
		
		private var m_sFileInfoUrl:String = "";
		private var m_FileInfo:SpLib.Tools.TDF = new SpLib.Tools.TDF;	
		private var m_RegetTimes:int = 0;
		
		public static function GetInstance(urlpath:String = ""):URLResMgr
		{
			var name:String = "SpLib.Net.URLResMgr";
			if(s_Instance==null)
			{
				s_Instance = SingletonFactory.Get(name) as SpLib.Net.URLResMgr;
				if(s_Instance==null)
				{			
					s_Instance = new SpLib.Net.URLResMgr(urlpath);
					SingletonFactory.Reg(name,s_Instance);
				}
			}
				
			return s_Instance;
		}
		
		public function URLResMgr(urlpath:String)
		{
			super();
			
			if(SpLib.Net.URLResMgr.s_Instance!=null)
			{
				throw new Error("URLResMgr is Singleton");
			}
			
			if(SingletonFactory.Get("SpLib.Net.URLResMgr")!=null)
			{
				throw new Error("URLResMgr is Singleton");
			}
		
			Init(urlpath);			
		}
		
		
		public static function MakeUrl(url:String):String
		{
			return GetInstance()._MakeUrl(url);
		}
		
		private function Init(urlpath:String):void
		{	
			s_sUrlPath = urlpath;
			m_sFileInfoUrl = urlpath;
			
			if(m_sFileInfoUrl.length==0)
			{
				this.dispatchEvent(new SpLibEvent(FILEINFO_COMPLETE));
				return;
			}
			
			m_sFileInfoUrl = urlpath + "files.txt?ver=" + Math.random().toString();			
			DownFileInfo();
		}
		
		private function DownFileInfo():void
		{
			var loader:flash.net.URLLoader = new flash.net.URLLoader;
			loader.addEventListener(Event.COMPLETE,OnFileInfoOk);
			loader.addEventListener(IOErrorEvent.IO_ERROR,OnIOError);
        	loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,OnSecurityError);
        	loader.addEventListener(ProgressEvent.PROGRESS,OnDownFileInfo);
        	
			loader.load(new URLRequest(m_sFileInfoUrl));
		}
		
		private function OnIOError(event:IOErrorEvent):void
		{
			++m_RegetTimes;
			if(m_RegetTimes<s_MaxRegetTimes)
			{
				DownFileInfo();
			}
			else
			{
				OnDownFileInfoErr();
			}	
		}
		
		private function OnSecurityError(event:SecurityErrorEvent):void
		{
			++m_RegetTimes;
			if(m_RegetTimes<s_MaxRegetTimes)
			{
				DownFileInfo();
			}
			else
			{
				OnDownFileInfoErr();
			}
		}
		
		private function OnDownFileInfoErr():void
		{
			this.dispatchEvent(new SpLibEvent(FILEINFO_FAIL));
		}
		
		private function OnDownFileInfo(evt:ProgressEvent):void
		{
			this.dispatchEvent(new SpLibEvent(FILEINFO_DOWNING,"OnProgress",[evt.bytesLoaded,evt.bytesTotal]));
		}
		
		private function OnFileInfoOk(evt:Event):void
		{
			var data:String = evt.target.data;
			m_FileInfo.LoadFromBuf(data);
			m_RegetTimes = 0;
			this.dispatchEvent(new SpLibEvent(FILEINFO_COMPLETE));
		}
		
		public function _MakeUrl(url:String):String
		{
			var fileurl:String;
			var filekey:String = m_FileInfo.GetStr(url,"FileKey");
			if(filekey.length==0)
			{
				fileurl = s_sUrlPath + "/" + url;
			}
			else
			{
				fileurl = s_sUrlPath + "/Files/" + url + "?ver=" + filekey;
			}
			
			return fileurl;
		}
	}
}